package com.fable.common.handler;

import cn.hutool.core.util.StrUtil;
import com.fable.common.eunm.AppHttpCodeEnum;
import com.fable.common.utils.JwtUtils;
import com.fable.common.utils.RedisUtil;
import com.fable.common.vo.ResultVO;
import com.fable.ntzw_ga.entity.SysUser;
import com.fable.ntzw_ga.service.ISysUserService;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Slf4j
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    @Value("${jwt.expiration}")
    private long expire;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Autowired
    JwtUtils jwtUtils;

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    UserDetailServiceImpl userDetailService;

    @Autowired
    ISysUserService sysUserService;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

        String authToken = request.getHeader(jwtUtils.getHeader());
        if (StrUtil.isBlankOrUndefined(authToken)) {
            chain.doFilter(request, response);
            return;
        }
        try {
            Claims claim = jwtUtils.getClaimByToken(authToken.replace(tokenHead,""));
            String username = claim.getSubject();
            // 获取用户的权限等信息
            SysUser sysUser = sysUserService.getByUsername(username);
            UsernamePasswordAuthenticationToken authentication
                    = new UsernamePasswordAuthenticationToken(username, null, userDetailService.getUserAuthority(sysUser.getId()));
            SecurityContextHolder.getContext().setAuthentication(authentication);
            chain.doFilter(request, response);
        } catch (ExpiredJwtException e) {
            log.error("JWT过期:{}", e.getMessage());
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            PrintWriter out=response.getWriter();
            out.write(new ObjectMapper().writeValueAsString(ResultVO.errorResult(AppHttpCodeEnum.TOKEN_EXPIRED)));
            out.flush();
            out.close();
        } catch (Exception e) {
            log.error("解析异常：", e);
            throw new RuntimeException("解析异常");
        }
    }
}
